﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SharpMUD.Framework.CorlibExtensions
{
	public static class System_Collections_Generic_Queue
	{
		public static T[] Dequeue<T>(this Queue<T> self,int count)
		{
            lock (self)
            {
                if (count < 0 || count > self.Count)
                    throw new IndexOutOfRangeException();

                List<T> resultsTemp = new List<T>();
                for (int x = 0; x < count && self.Count > 0; x++)
                {
                    resultsTemp.Add(self.Dequeue());
                }
                return resultsTemp.ToArray();
            }
		}

        public static T[] Peek<T>(this Queue<T> self, int count)
        {
            lock (self)
            {
                return self.ToArray().Take(count).ToArray();
            }
        }

        public static T GetValue<T>(this Queue<T> self, int index)
        {
            lock (self)
            {
                return (T)self.ToArray().GetValue(index);
            }
        }

        public static void Remove<T>(this Queue<T> self, T item)
        {
            lock(self)
            {
                if(self.Count==0)
                    return;
                else if(self.Count==1)
                    if(Object.Equals(self.Peek(),item))
                    {
                        self.Dequeue();
                        return;
                    }
                    else
                    {
                        return;
                    }
                else
                {
                    List<T> newQueueContents = new List<T>(self.ToArray());
                    if(newQueueContents.Contains(item)) newQueueContents.Remove(item);
                    self.Clear();
                    self.Enqueue(newQueueContents);
                    return;
                }
            }
        }

        public static int IndexOf<T>(this Queue<T> self, T item)
        {
            lock (self)
            {
                T[] array = self.ToArray<T>();
                for (int x = 0; x < array.Length; x++)
                {
                    if (Object.Equals(array[x], item))
                        return x;
                }
                return -1;
            }
        }

        public static void RemoveAt<T>(this Queue<T> self, int index)
        {
            lock (self)
            {
                if (index >= self.Count)
                    throw new IndexOutOfRangeException();

                if (index == 0)
                {
                    self.Dequeue();
                    return;
                }
                else 
                {
                    T[] originalContents = self.Dequeue(self.Count);
                    self.Clear();
                    if (index == (self.Count - 1))
                    {
                        self.Enqueue(originalContents.Take(index));
                        return;
                    }
                    else
                    {
                        self.Enqueue(originalContents.Take(index));
                        self.Enqueue(originalContents.Skip(index+1).Take(originalContents.Count()-(index+1)));
                        return;
                    }
                }                
            }
        }

        public static void Enqueue<T>(this Queue<T> self, IEnumerable<T> items)
        {
            lock (self)
            {
                foreach (var item in items)
                {
                    self.Enqueue(item);
                }
            }
        }
	}
}
